using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using FreeLancer.HRB.Services;
using FreeLancer.HRB.Domains;
using DevExpress.Web.Data;
using DevExpress.Web.ASPxGridView;
using FreeLancer.HRB.Core.Services;
using System.Threading;
using DevExpress.Web.ASPxEditors;

namespace FreeLancer.HRB.WebApp.Admin.Pages
{
  public partial class Users : System.Web.UI.Page
  {
    #region Page Events

    protected void Page_Init(object sender, EventArgs e)
    {
      InitializeData();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
      ((Admin)Master).SetActiveTab("Users");

      CreateUserWizard.CreatingUser += new LoginCancelEventHandler(CreateUserWizard_CreatingUser);
      CreateUserWizard.CreatedUser += new EventHandler(CreateUserWizard_CreatedUser);

      Page.Title = Resources.labels.users;

      if (!Page.IsPostBack)
      {
        if (!string.IsNullOrEmpty(Request["success"]))
        {
          if (Request["success"] == "true")
            lblInfo.Visible = true;
        }
      }

      lblErrorInvalidPassword.Visible = false;
      lblError.Visible = false;

      
    }

    #endregion

    #region CreateUserWizard Events

    void CreateUserWizard_CreatingUser(object sender, LoginCancelEventArgs e)
    {
      if (Membership.MinRequiredPasswordLength > CreateUserWizard.Password.Length)
      {
        e.Cancel = true;
        lblErrorInvalidPassword.Text =
          string.Format(lblErrorInvalidPassword.Text, Membership.MinRequiredPasswordLength);
        lblErrorInvalidPassword.Visible = true;
        lblInfo.Visible = false;

        return;
      }

      if (Membership.GetUser(CreateUserWizard.UserName) != null)
      {
        e.Cancel = true;
        lblError.Visible = true;
        lblInfo.Visible = false;

        return;
      }
    }

    /// <summary>
    /// Handles the CreatedUser event of the CreateUserWizard1 control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    void CreateUserWizard_CreatedUser(object sender, EventArgs e)
    {
      Response.Redirect("Users.aspx?success=true", true);
    }

    #endregion

    #region ASPxGridViewUser Events

    protected void ASPxGridViewUser_OnDeleting(object sender, ASPxDataDeletingEventArgs e)
    {
      if (e.Keys["UserID"] != null)
      {
        string username = e.Values["UserName"] as string;
        if (username == Thread.CurrentPrincipal.Identity.Name)
          throw new Exception(Resources.labels.infoDeleteCurrentUser);

        UsersService userService = new UsersService();
        int id = (int)e.Keys["UserID"];
          
        try
        {
          using (ConnectionScope.CreateTransaction())
          {
            userService.Delete(id);

            InitializeData();

            //Because do not use the SqlDataSource, 
            //so the grid do not have normal delete method.
            //Can handle it by canceling and going back to browser mode.
            e.Cancel = ConnectionScope.Complete();
          }
        }
        catch (Exception ex)
        {
          LoggingService.LogCritical("Admin-Users Page", "Exception when delete Users",
              ex, LoggingService.DefaultCategory, true); 
        }
      }
    }

    protected void ASPxGridViewUser_OnUpdating(object sender, ASPxDataUpdatingEventArgs e)
    {
      if (e.Keys["UserID"] != null)
      {
        UsersService userService = new UsersService();
        int id = (int)e.Keys["UserID"];
        TList<FreeLancer.HRB.Domains.Users> users =
          //(TList<FreeLancer.HRB.Domains.Users>)ASPxGridViewUser.DataSource;
          userService.GetAll();
        FreeLancer.HRB.Domains.Users user = users.Find("UserID", id);

        if (user != null)
        {
          user.EmailAddress = e.NewValues["EmailAddress"] as string;
          bool isAdmin = (bool)e.NewValues["IsAdministrators"];
          bool isSpecialist = (bool)e.NewValues["IsSpecialists"];
          try
          {
            using (ConnectionScope.CreateTransaction())
            {
              userService.Save(user);
              UpdateUserRole(user.UserId, isAdmin, isSpecialist);
              InitializeData();

              //Because do not use the SqlDataSource, 
              //so the grid do not have normal update method.
              //Can handle it by canceling and going back to browser mode.
              e.Cancel = ConnectionScope.Complete();
              ASPxGridViewUser.CancelEdit();
            }
          }
          catch (Exception ex)
          {
            LoggingService.LogCritical("Admin-Users Page", "Exception when update Users",
              ex, LoggingService.DefaultCategory, true); 
          }
        }
      }
    }

    protected void ASPxGridViewUser_OnCellEditorInitialize(object sender, ASPxGridViewEditorEventArgs e)
    {
      //GridViewDataComboBoxColumn column = ASPxGridViewUser.Columns[4] as GridViewDataComboBoxColumn;
      //if (e.Column == column)
      //{
      //  RolesService roleService = new RolesService();
      //  TList<FreeLancer.HRB.Domains.Roles> roles = roleService.GetAll();

      //  ((ASPxComboBox)e.Editor).Items.Clear();
      //  foreach (FreeLancer.HRB.Domains.Roles role in roles)
      //  {
      //    ((ASPxComboBox)e.Editor).Items.Add(role.Role, role.RoleId);
      //  }
      //}
    }

    #endregion

    #region Helper Methods

    private void InitializeData()
    {
      try
      {
        UsersService service = new UsersService();
        //TList<FreeLancer.HRB.Domains.Users> users = service.GetAll()
        DataSet dtsUser = service.GetAllWithRole(0);
        ASPxGridViewUser.DataSource = dtsUser.Tables[0];
        ASPxGridViewUser.DataBind();
      }
      catch (Exception ex)
      {
        LoggingService.LogCritical("Admin-Users Page", "Exception when get Users", 
          ex, LoggingService.DefaultCategory, true); 
      }
    }

    private void UpdateUserRole(int userId, bool isAdmin, bool isSpecialist)
    {
      int total = 0;
      UserRolesService service = new UserRolesService();
      TList<UserRoles> userRoles = service.GetPaged("UserId=" + userId + " AND RoleId=1", string.Empty, 0, 1, out total);
      if (userRoles.Count > 0)
      {
        //Admin role
        if (!isAdmin)
          service.Delete(userRoles[0]);
      }
      else
      {
        //New role
        if (isAdmin)
        {
          UserRoles userRole = new UserRoles();
          userRole.RoleId = 1;
          userRole.UserId = userId;
          service.Save(userRole);
        }
      }

      userRoles = service.GetPaged("UserId=" + userId + " AND RoleId=2", string.Empty, 0, 1, out total);

      if (userRoles.Count > 0)
      {
        //Admin role
        if (!isSpecialist)
          service.Delete(userRoles[0]);
      }
      else
      {
        //New role
        if (isSpecialist)
        {
          UserRoles userRole = new UserRoles();
          userRole.RoleId = 2;
          userRole.UserId = userId;
          service.Save(userRole);
        }
      }
    }

    #endregion
  }
}
